﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using LiveCharts;
using LiveCharts.Wpf;

namespace 数据挖掘实验
{
    /// <summary>
    /// 朴素贝叶斯基本算法
    /// </summary>
    public partial class MainWindow
    {
        BayesClassifier bayesClassifier = new BayesClassifier(); // 贝叶斯分类器
        Dictionary<string, string> bayesInputDic = new Dictionary<string, string>(); // 输入的特征的值
        List<TextBox> bayesTextBoxs = new List<TextBox>(); // 所有的特征值文本框
        bool? bayesIgnore = true; // 启用忽略

        /// <summary>
        /// 对贝叶斯算法界面进行初始化
        /// </summary>
        void InitialBayes()
        {
            MouseButtonEventHandler focusEvent = (sender, e) =>
            {
                AutoDetectText.Focus();
                AutoDetectText.SelectAll();
            };
            AutoDetectText.AddHandler(MouseLeftButtonDownEvent, focusEvent, true);
            BayesChartScroll.Visibility = Visibility.Hidden;
            bayesClassifier.onLog += (info, newInfo) =>
            {
                BayesOutput.Document.Blocks.Add(RichTextFormatter.Format(newInfo));
            };
            InitialBayesChart();
        }
        
        /// <summary>
        /// 对贝叶斯算法可视化图表进行初始化
        /// </summary>
        void InitialBayesChart()
        {
            bayesAxisT.Title = "可能性/%";
            bayesAxisT.LabelFormatter = value => $"{value * 100:0.00}%";

            DataContext = this;
        }

        /// <summary>
        /// 点击贝叶斯算法页面的选择文件
        /// </summary>
        void Bayes_File_Read_Button_Click(object sender, RoutedEventArgs e)
        {
            var openFileDialog = new Microsoft.Win32.OpenFileDialog()
            {
                Filter = "文本文件(*.txt)|*.txt|所有文件(*.*)|*.*"
            };
            var result = openFileDialog.ShowDialog();
            if (result == true)
            {
                bayesTextBoxs.Clear();
                BayesOutput.Document.Blocks.Clear();
                FeatureItems.Children.Clear();
                bayesInputDic.Clear();
                string path = openFileDialog.FileName;
                BayesFileNameLabel.Content = path;

                bayesClassifier.Open(path);
                string[] titles = bayesClassifier.Titles;
                for (int i = 1; i < titles.Length - 1; i++) // 添加特征
                {
                    string title = titles[i];
                    BayesAddFeature(title, "");
                }
            }
        }


        /// <summary>
        /// 在特征列表中添加特征输入框
        /// </summary>
        void BayesAddFeature(string tag, string content)
        {
            var grid = new Grid(); // 创建一个网格用于存放标签(Label)和输入框(TextBox)
            var label = new Label {Content = tag, Height = 24}; // 特征的标签组件
            var text = new TextBox
            {
                Margin = new Thickness(0, 0, 0, 10),
                Text = content,
                HorizontalAlignment = HorizontalAlignment.Left,
                VerticalAlignment = VerticalAlignment.Top,
                Width = FeatureGrid.Width - 80,
                Height = 24
            }; // 输入特征的文本框
            text.Margin = new Thickness(60, 0, 0, 0);
            text.VerticalContentAlignment = VerticalAlignment.Center;
            MouseButtonEventHandler focusEvent = (sender, e) =>
            {
                text.Focus();
                text.SelectAll();
            }; // 单击文本框自动进行全选
            text.AddHandler(MouseLeftButtonDownEvent, focusEvent, true); // 注册自动全选文本事件
            grid.Children.Add(label);
            grid.Children.Add(text);
            FeatureItems.Children.Add(grid);
            bayesTextBoxs.Add(text);

            bayesInputDic.TryAdd(tag, "");
            text.TextChanged += (sender, e) => // 输入框改变时改变特征信息
            {
                bayesInputDic[tag] = text.Text;
            };
        }

        /// <summary>
        /// 自动分割粘贴进来的信息填充到特征信息
        /// </summary>
        void BayesAutoDetectText_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (AutoDetectText.Text == "智能识别框")
            {
                return;
            }

            var datas = AutoDetectText.Text.Split(',');
            if (datas.Length == bayesTextBoxs.Count)
            {
                for (int i = 0; i < bayesTextBoxs.Count; i++)
                {
                    TextBox text = bayesTextBoxs[i];
                    text.Text = datas[i];
                }
            }
            else
                MessageBox.Show($"不匹配的数据数目{datas.Length} {bayesTextBoxs.Count}");

            AutoDetectText.Text = "智能识别框";
        }

        /// <summary>
        /// 对结果进行计算
        /// </summary>
        void BayesRecognition_Click(object sender, RoutedEventArgs e)
        {
            BayesOutput.Document.Blocks.Clear(); // 清空输出信息框
            if (!bayesClassifier.Current) // 未选择数据集文件时需要选择数据集文件
            {
                MessageBox.Show("请先选择数据集");
                Bayes_File_Read_Button_Click(null, null);
                return;
            }

            var args = bayesInputDic.Select(pair => pair.Value).ToArray(); // 将所有输入的特征的值提取出来
            Dictionary<string, BayesClassifier.ResInfo>
                infos = bayesClassifier.Matching(args, bayesIgnore); // 使用贝叶斯分类器进行分类

            BayesDrawChart(infos); // 根据计算结果绘制柱状图
        }

        /// <summary>
        /// 根据结果集绘制柱状图
        /// </summary>
        /// <param name="reses">贝叶斯算法计算出的结果集</param>
        void BayesDrawChart(Dictionary<string, BayesClassifier.ResInfo> reses)
        {
            if (ReferenceEquals(reses, null)) // 没有计算结果
            {
                return;
            }

            var values = reses.Values.Select(x => x.val).ToArray(); // 提取绝对百分比
            float total = values.Sum(); // 绝对百分比加和
            values = values.Select(x => total == 0 ? 1 : x / total).ToArray(); // 计算相对百分比，如果都不可能是(可能性比率为0)考虑后显示为都有可能是
            
            var bayesPercentColumn = new ColumnSeries {Title = "可能性", ScalesYAt = 0};
            BayesChart.Series = new SeriesCollection {bayesPercentColumn};
            bayesPercentColumn.Values = new ChartValues<float>(values); // 传入计算值
            bayesAxisV.Title = bayesClassifier.ResultTitle; // 贝叶斯计算的结论标签
            bayesAxisV.Labels = bayesClassifier.ResultLabels; // 贝叶斯计算的结论值
        }

        bool bayesOutputMode = true; // 是否为日志模式，否则为图表展示模式

        /// <summary>
        /// 切换日志/图表模式按钮被按下
        /// </summary>
        void BayesExhabitChange_Click(object sender, RoutedEventArgs e)
        {
            bayesOutputMode = !bayesOutputMode;
            BayesOutputScroll.Visibility = ConvertBoolToVisibility(bayesOutputMode);
            BayesChartScroll.Visibility = ConvertBoolToVisibility(!bayesOutputMode);
        }

        /// <summary>
        /// 禁用忽略(输入除了空信息以外的数据会参与到计算)
        /// </summary>
        void BayesIgnore_Checked(object sender, RoutedEventArgs e)
        {
            bayesIgnore = BayesIgnoire.IsChecked;
        }
    }
}